package com.hsteach.service.wage;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import com.hsteach.common.exception.ServiceException;
import com.hsteach.common.utils.DateUtils;
import com.hsteach.common.utils.SecurityUtils;
import com.hsteach.dao.domain.wage.WageTemplateItems;
import com.hsteach.dao.mapper.wage.WageTemplateItemsMapper;
import com.hsteach.enums.BooleanEnum;
import com.hsteach.enums.WageDefaultTemp1Enum;
import com.hsteach.enums.WageDefaultTemp2Enum;
import com.hsteach.enums.WageDefaultTempNameEnum;
import com.hsteach.web.controller.wage.dto.AddWageTemplateDto;
import com.hsteach.web.controller.wage.dto.UpdateWageTemplateDto;
import com.hsteach.web.controller.wage.dto.WageTemplateItemDto;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.hsteach.dao.mapper.wage.WageTemplateMapper;
import com.hsteach.dao.domain.wage.WageTemplate;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

/**
 * 工资模版Service业务层处理
 *
 * @author fanxquer
 * @date 2023-07-13
 */
@Service
public class WageTemplateService
{
    @Autowired
    private WageTemplateMapper wageTemplateMapper;

    @Autowired
    private WageTemplateItemsMapper wageTemplateItemsMapper;

    /**
     * 查询工资模版
     *
     * @param id 工资模版主键
     * @return 工资模版
     */
    public UpdateWageTemplateDto selectWageTemplateById(Long id)
    {
        WageTemplate wageTemplate = wageTemplateMapper.selectWageTemplateById(id);
        WageTemplateItems query = new WageTemplateItems();
        query.setTemplateId(id);
        List<WageTemplateItems> wageTemplateItems = wageTemplateItemsMapper.selectWageTemplateItemsList(query);
        List<WageTemplateItemDto> itemDtos = wageTemplateItems.stream().map(e -> {
            WageTemplateItemDto dto = new WageTemplateItemDto();
            BeanUtils.copyProperties(e, dto);
            return dto;
        }).collect(Collectors.toList());
        UpdateWageTemplateDto tempDto = new UpdateWageTemplateDto();
        BeanUtils.copyProperties(wageTemplate, tempDto);
        tempDto.setItems(itemDtos);
        return tempDto;
    }

    /**
     * 查询工资模版列表
     *
     * @param wageTemplate 工资模版
     * @return 工资模版
     */
    @Transactional(rollbackFor = Exception.class)
    public List<WageTemplate> selectWageTemplateList(WageTemplate wageTemplate)
    {
        wageTemplate.setOrgCode(SecurityUtils.getAuthInfo().getOrgCode());
        List<WageTemplate> wageTemplates = wageTemplateMapper.selectWageTemplateList(wageTemplate);
        //筛选出初始不能删除的模板
        List<String> canDeleteTemplateList = wageTemplates.stream().filter((e) -> e.getCanDelete().equals(BooleanEnum.FALSE.getStrCode())).map(WageTemplate::getTemplateName).collect(Collectors.toList());
        //第一套模板不存在则插入模板（学校聘用人员工资模板）
        if (!canDeleteTemplateList.contains(WageDefaultTempNameEnum.TEMPLATE1.getName())) {
            WageTemplate add = new WageTemplate();
            add.setOrderId(1L);
            add.setTemplateName(WageDefaultTempNameEnum.TEMPLATE1.getName());
            add.setIsDefault(Boolean.FALSE);
            add.setOrgCode(SecurityUtils.getAuthInfo().getOrgCode());
            add.setDelFlg(BooleanEnum.FALSE.getCode());
            add.setBuiltInFlg(BooleanEnum.FALSE.getCode());
            add.setCanDelete(BooleanEnum.FALSE.getStrCode());
            wageTemplateMapper.insertWageTemplate(add);
            List<WageTemplateItems> defaultItems = WageDefaultTemp1Enum.getDefaultItems(add.getId());
            wageTemplateItemsMapper.batchInsert(defaultItems);
            //重新查询
            wageTemplates = wageTemplateMapper.selectWageTemplateList(wageTemplate);
        }
        //第二套模板不存在则插入模板（学校在编人员工资模版）
        if (!canDeleteTemplateList.contains(WageDefaultTempNameEnum.TEMPLATE2.getName())) {
            WageTemplate add = new WageTemplate();
            add.setOrderId(1L);
            add.setTemplateName(WageDefaultTempNameEnum.TEMPLATE2.getName());
            add.setIsDefault(Boolean.TRUE);
            add.setOrgCode(SecurityUtils.getAuthInfo().getOrgCode());
            add.setDelFlg(BooleanEnum.FALSE.getCode());
            add.setBuiltInFlg(BooleanEnum.FALSE.getCode());
            add.setCanDelete(BooleanEnum.FALSE.getStrCode());
            wageTemplateMapper.insertWageTemplate(add);
            List<WageTemplateItems> defaultItems = WageDefaultTemp2Enum.getDefaultItems(add.getId());
            wageTemplateItemsMapper.batchInsert(defaultItems);
            //重新查询
            wageTemplates = wageTemplateMapper.selectWageTemplateList(wageTemplate);
        }
        //将初始模板放于最前
        List<WageTemplate> result = new ArrayList<>();
        wageTemplates.forEach(item -> {
            if (item.getCanDelete().equals(BooleanEnum.FALSE.getStrCode())  && item.getTemplateName().equals(WageDefaultTempNameEnum.TEMPLATE2.getName())) {
                result.add(item);
            }
        });
        wageTemplates.forEach(item -> {
            if (item.getCanDelete().equals(BooleanEnum.FALSE.getStrCode()) && item.getTemplateName().equals(WageDefaultTempNameEnum.TEMPLATE1.getName())) {
                result.add(item);
            }
        });
        wageTemplates.forEach(item -> {
            if (!item.getCanDelete().equals(BooleanEnum.FALSE.getStrCode())) {
                result.add(item);
            }
        });
        return result;
    }

    /**
     * 新增工资模版
     *
     * @param wageTemplate 工资模版
     * @return 结果
     */
    public int insertWageTemplate(WageTemplate wageTemplate)
    {
        wageTemplate.setCreateTime(DateUtils.getNowDate());
        return wageTemplateMapper.insertWageTemplate(wageTemplate);
    }

    /**
     * 新增工资模版
     *
     * @return 结果
     */
    public int addWageTemplate(AddWageTemplateDto dto)
    {

        WageTemplate wageTemplate = new WageTemplate();
        wageTemplate.setTemplateName(dto.getTemplateName());
        wageTemplate.setOrgCode(SecurityUtils.getAuthInfo().getOrgCode());
        wageTemplate.setDelFlg(BooleanEnum.FALSE.getCode());
        List<WageTemplate> wageTemplates = wageTemplateMapper.selectWageTemplateList(wageTemplate);
        if (wageTemplates.size() > 0) {
            throw new ServiceException("模板已存在");
        }
        wageTemplate.setIsDefault(Boolean.FALSE);
        wageTemplate.setCreateBy(SecurityUtils.getAuthInfo().getId());
        wageTemplate.setCanDelete(String.valueOf(BooleanEnum.TRUE.getCode()));
        Long max = wageTemplateMapper.selectMaxOrder(wageTemplate.getOrgCode());
        if (max == null) {
            wageTemplate.setOrderId(1L);
        } else {
            wageTemplate.setOrderId(max + 1);
        }
        int i = wageTemplateMapper.insertWageTemplate(wageTemplate);
        List<WageTemplateItems> items = dto.getItems().stream().map(e -> {
            WageTemplateItems item = new WageTemplateItems();
            BeanUtils.copyProperties(e, item);
            item.setTemplateId(wageTemplate.getId());
            if (item.getStatus() == null) {
                item.setStatus(BooleanEnum.TRUE.getCode());
            }
            return item;
        }).collect(Collectors.toList());
        wageTemplateItemsMapper.batchInsert(items);
        return i;
    }

    public int copy(Long id) {
        WageTemplate wageTemplate = wageTemplateMapper.selectWageTemplateById(id);
        WageTemplateItems item = new WageTemplateItems();
        item.setTemplateId(id);
        List<WageTemplateItems> items = wageTemplateItemsMapper.selectWageTemplateItemsList(item);
        AddWageTemplateDto tempDto = new AddWageTemplateDto();
        BeanUtils.copyProperties(wageTemplate, tempDto);
        List<WageTemplateItemDto> itemDtos = items.stream().map(e -> {
            WageTemplateItemDto dto = new WageTemplateItemDto();
            BeanUtils.copyProperties(e, dto);
            return dto;
        }).collect(Collectors.toList());
        tempDto.setItems(itemDtos);

        tempDto.setTemplateName(tempDto.getTemplateName() + "-副本");
        WageTemplate query = new WageTemplate();
        query.setLeftName(tempDto.getTemplateName());
        query.setOrgCode(SecurityUtils.getAuthInfo().getOrgCode());
        query.setDelFlg(BooleanEnum.FALSE.getCode());
        List<WageTemplate> wageTemplates = wageTemplateMapper.selectWageTemplateList(query);
        if (wageTemplates.size() > 0) {
            tempDto.setTemplateName(tempDto.getTemplateName() + wageTemplates.size());
        }
        return addWageTemplate(tempDto);
    }

    /**
     * 修改工资模版
     *
     * @return 结果
     */
    public int updateWageTemplate(UpdateWageTemplateDto dto)
    {
        //判断能否修改
        boolean canDelFlag = wageTemplateMapper.selectCanDelete(dto.getId()) != 0;
        if (!canDelFlag) {
            throw new ServiceException("初始模版无法修改");
        }
        wageTemplateItemsMapper.deleteByTemplateId(dto.getId());
        List<WageTemplateItems> items = dto.getItems().stream().map(e -> {
            WageTemplateItems item = new WageTemplateItems();
            BeanUtils.copyProperties(e, item);
            item.setTemplateId(dto.getId());
            return item;
        }).collect(Collectors.toList());
        wageTemplateItemsMapper.batchInsert(items);
        WageTemplate wageTemplate = new WageTemplate();
        wageTemplate.setTemplateName(dto.getTemplateName());
        wageTemplate.setId(dto.getId());
        return wageTemplateMapper.updateWageTemplate(wageTemplate);
    }

    /**
     * 设置为默认模版
     * @param id
     * @return
     */
    public int updateDefault(Long id) {
        wageTemplateMapper.updateNotDefaultByOrgCode(SecurityUtils.getAuthInfo().getOrgCode());
        WageTemplate wageTemplate = new WageTemplate();
        wageTemplate.setId(id);
        wageTemplate.setIsDefault(Boolean.TRUE);
        return wageTemplateMapper.updateWageTemplate(wageTemplate);
    }


    /**
     * 批量删除工资模版
     *
     * @param ids 需要删除的工资模版主键
     * @return 结果
     */
    public int deleteWageTemplateByIds(Long[] ids)
    {
        if (ids.length == 0) {
            return -1;
        }
        //根据ID查询模板数据
        List<WageTemplate> list =  wageTemplateMapper.batchSelectCanDeleteFlagById(ids);
        //筛选出可以删除的模板主键
        List<Long> idList = list.stream().filter(Objects::nonNull).filter(e -> {
            if (BooleanEnum.FALSE.getStrCode().equals(e.getCanDelete())) {
                return false;
            }
            return true;
        }).map(WageTemplate::getId).collect(Collectors.toList());
        if (ObjectUtils.isEmpty(idList)) {
            return -1;
        }
        Long[] deleteIdList = idList.toArray(new Long[0]);
        return wageTemplateMapper.deleteWageTemplateByIds(deleteIdList);
    }

    /**
     * 删除工资模版信息
     *
     * @param id 工资模版主键
     * @return 结果
     */
    public int deleteWageTemplateById(Long id)
    {
        WageTemplate wageTemplate = wageTemplateMapper.selectWageTemplateById(id);
        if (BooleanEnum.TRUE.getCode().equals(wageTemplate.getBuiltInFlg())) {
            throw new ServiceException("内置模版无法删除");
        }
        if (BooleanEnum.FALSE.getStrCode().equals(wageTemplate.getCanDelete())) {
            throw new ServiceException("初始模版无法删除");
        }
        return wageTemplateMapper.updateDelFlg(id);
    }
}
